package tpoo.client.ui.views;

import static tpoo.common.services.utils.ServiceConstants.USER_SERVICE;

import java.util.List;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import tpoo.client.Activator;
import tpoo.client.ui.dialogs.AddContactDialog;
import tpoo.client.ui.editors.ChatEditor;
import tpoo.client.ui.editors.ChatEditorInput;
import tpoo.client.ui.widgets.MyTableViewer;
import tpoo.common.dto.model.users.UserDTO;
import tpoo.common.services.UserService;
import tpoo.common.services.exceptions.ServiceException;
import tpoo.common.services.utils.ServiceAdmin;
import tpoo.common.utils.UserSession;

/**
 * This sample class demonstrates how to plug-in a new workbench view. The view
 * shows data obtained from the model. The sample creates a dummy model on the
 * fly, but a real implementation would connect to the model available either in
 * this or another plug-in (e.g. the workspace). The view is connected to the
 * model using a content provider.
 * <p>
 * The view uses a label provider to define how model objects should be
 * presented in the view. Each view can present the same model objects using
 * different labels and icons, if needed. Alternatively, a single label provider
 * can be shared between views in order to ensure that objects of the same type
 * are presented in the same way everywhere.
 * <p>
 * 
 * author diego
 */

public class ContactsView extends ViewPart {

	public static String ID = "tpoo-client.views.ContactsView";

	private MyTableViewer viewer;
	private WritableList input;
	private Action addContactAction;
	private Action doubleClickAction;

	/*
	 * The content provider class is responsible for providing objects to the
	 * view. It can wrap existing objects in adapters or simply return objects
	 * as-is. These objects may be sensitive to the current input of the view,
	 * or ignore it and always show the same content (like Task List, for
	 * example).
	 */

	class ViewContentProvider implements IStructuredContentProvider {
		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
		}

		public void dispose() {
		}

		public Object[] getElements(Object parent) {
			try {
				UserDTO udto = UserSession.getInstance().getUser();
				UserService us = (UserService) ServiceAdmin.getService(USER_SERVICE);
				List<UserDTO> contactsdtos = us.getContacts(udto);
				return getContactsArray(contactsdtos);
			} catch (ServiceException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}

		private Object[] getContactsArray(List<UserDTO> contactsdtos) {
			if (contactsdtos.isEmpty())
				return new String[] { "NO CONTACTS" };
			else {
				UserDTO[] contacts = new UserDTO[contactsdtos.size()];
				int i = 0;
				for (UserDTO contactDTO : contactsdtos)
					contacts[i++] = contactDTO;
				return contacts;
			}
		}
	}

	class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
		public String getColumnText(Object obj, int index) {
			return getText(obj);
		}

		public Image getColumnImage(Object obj, int index) {
			return getImage(obj);
		}

		public Image getImage(Object obj) {
			//return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
			return Activator.getImageDescriptor("icons/user.png").createImage(true);
		}

		@Override
		public String getText(Object element) {
			//TODO analizar el instanceof, el problema es la interfaz de LabelProvider
			if (element instanceof UserDTO)
				return ((UserDTO) element).getUsername();
			else
				return super.getText(element);
		}
	}

	static class NameSorter extends ViewerSorter {
	}

	/**
	 * The constructor.
	 */
	public ContactsView() {
	}

	//private Text name, lastMessage;

	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {

		viewer = new MyTableViewer(parent, SWT.MULTI | SWT.H_SCROLL	| SWT.V_SCROLL);
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setSorter(new NameSorter());
		viewer.setInput(getViewSite());

		//name = new Text(parent, SWT.BORDER);
		/*
		 * final GridData gd_name = new GridData(SWT.FILL, SWT.CENTER, true,
		 * false); name.setLayoutData(gd_name);
		 */
		// Create the help context id for the viewer's control
		PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(),	"tpoo-client.viewer");
		makeActions();
		hookContextMenu();
		hookDoubleClickAction();
		contributeToActionBars();

		initDataBindings();

	}

	private DataBindingContext bindingContext;

	private void initDataBindings() {
		UserDTO udto = UserSession.getInstance().getUser();

		//ej. de binding
		/*
		bindingContext = new DataBindingContext();

		IObservableValue nameTextObserveWidget = SWTObservables.observeText(name, SWT.Modify);
		IObservableValue personNameObserveValue = BeansObservables.observeValue(udto, "lastMessage");
		bindingContext.bindValue(nameTextObserveWidget, personNameObserveValue,	null, null);
		*/
		udto.addObserver(viewer);
	}

	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager("#PopupMenu");
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				ContactsView.this.fillContextMenu(manager);
			}
		});
		Menu menu = menuMgr.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(menuMgr, viewer);
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalPullDown(bars.getMenuManager());
		fillLocalToolBar(bars.getToolBarManager());
	}

	private void fillLocalPullDown(IMenuManager manager) {
		manager.add(addContactAction);
		//manager.add(new Separator());		
	}

	private void fillContextMenu(IMenuManager manager) {
		manager.add(addContactAction);
		// Other plug-ins can contribute there actions here
		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}

	private void fillLocalToolBar(IToolBarManager manager) {
		manager.add(addContactAction);
	}

	private void makeActions() {
		addContactAction = new Action() {
			public void run() {
				UserService us;
				try {
					AddContactDialog addContact = new AddContactDialog(
							getSite().getShell());
					if (addContact.open() == Dialog.OK) {
						us = (UserService) ServiceAdmin
								.getService(USER_SERVICE);
						us.addContact(UserSession.getInstance().getUser(),
								addContact.getContactName());
						viewer.refresh();
					}
				} catch (ServiceException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		};
		addContactAction.setText("Agregar Contacto");
		addContactAction.setToolTipText("Agregar un contacto");
		addContactAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
				.getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));


		doubleClickAction = new Action() {
			public void run() {
				ISelection selection = viewer.getSelection();
				Object obj = ((IStructuredSelection) selection)
						.getFirstElement();
				try {

					//Abro el chat
					IWorkbenchPage page = PlatformUI.getWorkbench()
							.getActiveWorkbenchWindow().getActivePage();
					ChatEditorInput input = new ChatEditorInput(((UserDTO) obj).getUsername());
					try {
						page.openEditor(input, ChatEditor.ID);
					} catch (PartInitException e) {
						e.printStackTrace();
					}

					
					
				/*
					InputDialog id = new InputDialog(getSite().getShell(),
							"Mensaje a enviar", "Poner el texto acá", "", null);
					if (id.open() == InputDialog.OK) {
						UserDTO contact = (UserDTO) obj;
						UserService us = (UserService) ServiceAdmin
								.getService(USER_SERVICE);
						UserDTO udto = UserSession.getInstance().getUser();
						us.sendMessage(udto, contact, id.getValue());
					}
					
				} catch (ServiceException e) {
					e.printStackTrace();
				*/
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
	}

	private void hookDoubleClickAction() {
		viewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				doubleClickAction.run();
			}
		});
	}

	@Deprecated
	private void showMessage(String message) {
		MessageDialog.openInformation(viewer.getControl().getShell(),
				"Contact View", message);
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}
}